package com.example.studentinfo.config;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.*;
import com.fasterxml.jackson.datatype.jsr310.ser.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;


@Configuration
public class JacksonConfig {


    public static ObjectMapper defaultObjectMapper() {
        ObjectMapper mapper = JsonMapper.builder().enable(MapperFeature.USE_STD_BEAN_NAMING)
                .propertyNamingStrategy(new PropertyNamingStrategy.PropertyNamingStrategyBase() {
                    @Override
                    public String translate(String propertyName) {
                        return StringUtils.uncapitalize(propertyName);
                    }
                })
                .build();

        // 格式化Date类型的数据
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

        // 不序列化空值
        mapper.setSerializationInclusion(Include.NON_NULL);


        SimpleModule simpleModule = new SimpleModule();
        // 序列换成json时,将所有的long变成string 因为js中得数字类型不能包含所有的java long值
        simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        // BigDecimal--保留两位小数转为字符串 如果是0变为0.00这种

        //序列化时 格式化DateTime类型的数据
        simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        simpleModule.addSerializer(LocalDate.class,
                new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        simpleModule.addSerializer(LocalTime.class,
                new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        simpleModule.addSerializer(YearMonth.class,
                new YearMonthSerializer(DateTimeFormatter.ofPattern("yyyy-MM")));
        simpleModule.addSerializer(MonthDay.class,
                new MonthDaySerializer(DateTimeFormatter.ofPattern("MM-dd")));

        //反序列化时 格式化DateTime类型的数据
        simpleModule.addDeserializer(LocalDateTime.class,
                new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        simpleModule.addDeserializer(LocalDate.class,
                new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        simpleModule.addDeserializer(LocalTime.class,
                new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        simpleModule.addDeserializer(YearMonth.class,
                new YearMonthDeserializer(DateTimeFormatter.ofPattern("yyyy-MM")));
        simpleModule.addDeserializer(MonthDay.class,
                new MonthDayDeserializer(DateTimeFormatter.ofPattern("MM-dd")));

        // 去除前后空格
        simpleModule.addDeserializer(String.class, new StdScalarDeserializer<>(String.class) {
            @Override
            public String deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
                String value = jsonParser.getValueAsString();
                if (StringUtils.isBlank(value)) {
                    return null;
                }
                return value.trim();
            }
        });
        mapper.registerModule(simpleModule);
        return mapper;
    }


    @Bean
    public ObjectMapper objectMapper() {
        return defaultObjectMapper();
    }
}